/*
 * Copyright 2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 2017-07-26  wuhq  add  accept wifi display invite  auto
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_NDEBUG 0
#define LOG_TAG "wfd"
#include <utils/Log.h>

#include "sink/WifiDisplaySink.h"
#include "source/WifiDisplaySource.h"

#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <gui/SurfaceComposerClient.h>
#include <media/AudioSystem.h>
#include <media/IMediaPlayerService.h>
#include <media/IRemoteDisplay.h>
#include <media/IRemoteDisplayClient.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/foundation/ADebug.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cutils/properties.h> // for property_get

#include "wpa_ctrl.h"
#include "eloop.h"
#include <fcntl.h>  
#include <sys/file.h>

#define TRY_ARP_COUNT 36
#define MAX_CLIENT 1 
#define MAC_SIZE    23 
#define DEFAULT_GROUP_INTENT    6


//#define PID_WFD "/storage/pid_wfd"

static const char *pid_wfd = "/storage/pid_wfd";

struct thread_table {
    pid_t pid;
    unsigned char mac[MAC_SIZE];
    bool isclient;
};


static struct thread_table   gthread_table[MAX_CLIENT];

static int wpa_ctrl_cmd(struct wpa_ctrl *ctrl_conn, const char *cmd);

static int Search_ipAddr(const char *hwSrcAddr,char *IpAddr, int iCount)
{
	//FILE *fp = fopen("/data/misc/dhcp/dnsmasq.leases", "rb");
	FILE *fp = fopen("/proc/net/arp", "rb");
	ALOGI("############## %d ", iCount);
	int iRet =-1;
	if (fp)
	{
			char *save_ptr;
			char *id, *hwAddr,*ipAddr,*hwType,*Flag,*Mash,*Device;
			char line[255];				
			while(fgets(line, sizeof(line), fp)) {
				const char *delim = " ";
				
				line[strlen(line)-1] = '\0';
				ALOGI("line =%s",line);

				if (!(ipAddr = strtok_r(line, delim, &save_ptr))) {
					ALOGI("Error parsing hwAddr");
				}
				
				if (!(hwType = strtok_r(NULL, delim, &save_ptr))) {
					ALOGI("Error parsing hwType");
				}
				if (!(Flag = strtok_r(NULL, delim, &save_ptr))) {
					ALOGI("Error parsing hwType");
				}				
				if (!(hwAddr = strtok_r(NULL, delim, &save_ptr))) {
					ALOGI("Error parsing hwAddr");
				}
				if (!(Mash = strtok_r(NULL, delim, &save_ptr))) {
					ALOGI("Error parsing Mash");
				}
				if (!(Device = strtok_r(NULL, delim, &save_ptr))) {
					ALOGI("Error parsing Device");
				}				
				ALOGI("Device =%s, hwAddr %s, hwSrcAddr %s",Device, hwAddr, hwSrcAddr);
                if ((iCount >= TRY_ARP_COUNT/2  && memcmp("p2p-p2p",Device,strlen("p2p")) == 0 && memcmp("0x2",Flag,3) == 0) 
                || (memcmp("p2p-p2p",Device,strlen("p2p"))==0 && memcmp("0x2",Flag,3)==0 && memcmp(hwSrcAddr,hwAddr,strlen(hwSrcAddr)) == 0)
				|| (memcmp("192.168.49.1",ipAddr,strlen("192.168.49.1")) == 0))
 //               || (memcmp("p2p-p2p",Device,strlen("p2p"))==0 && memcmp("0x2",Flag,3)==0 && memcmp(hwSrcAddr,hwAddr,strlen(hwSrcAddr)) == 0))
				{
				    memcpy(IpAddr,ipAddr,strlen(ipAddr));
				    ALOGI("####IpAddr ==%s",IpAddr);
				    iRet =1;
				    break;						
				}
			}
			fclose(fp);
			return iRet;
			
		}
	return iRet;
}


#include <sys/poll.h> 

const char wpa_cmd_find[] = "P2P_FIND 120";
const char wpa_cmd_set_wifi_dislay[] = "SET wifi_display 1";
const char wpa_cmd_set_subelem[] = "WFD_SUBELEM_SET 0 000601111c440032";
const char wpa_cmd_stop_find[] = "P2P_STOP_FIND";

const char wpa_cmd_peer[] = "P2P_PEER";
const char wpa_cmd_connect[] = "P2P_CONNECT";

static struct wpa_ctrl *ctrl_conn = NULL;
static struct wpa_ctrl *mon_conn = NULL;


static int sta_count = 0;
  
int wifi_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len);

int wifi_wait_for_event(char *buf, size_t buflen)
{
    struct wpa_ctrl *monitor_conn = mon_conn;
    size_t nread = buflen - 1;

    int result;

    if (monitor_conn == NULL) {

        ALOGD("Connection closed\n");

        strncpy(buf, WPA_EVENT_TERMINATING " - connection closed", buflen-1);
        buf[buflen-1] = '\0';

        return strlen(buf);
    }

    result = wifi_ctrl_recv(monitor_conn, buf, &nread);
    if (result < 0) {
        
        ALOGD("wifi_ctrl_recv failed: %s\n", strerror(errno));
        strncpy(buf, WPA_EVENT_TERMINATING " - recv error", buflen-1);
        buf[buflen-1] = '\0';

        return strlen(buf);
    }

    buf[nread] = '\0';

    /* LOGD("wait_for_event: result=%d nread=%d string=\"%s\"\n", result, nread, buf); */
    /* Check for EOF on the socket */
    if (result == 0 && nread == 0) {
                 
        /* Fabricate an event to pass up */
        ALOGD("Received EOF on supplicant socket\n");

        strncpy(buf, WPA_EVENT_TERMINATING " - signal 0 received", buflen-1);
        buf[buflen-1] = '\0';

        return strlen(buf);
    }

/*
*     * Events strings are in the format
*     *     <N>CTRL-EVENT-XXX
*     *
*     * where N is the message level in numerical form (0=VERBOSE, 1=DEBUG,
*     * etc.) and XXX is the event name. The level information is not useful
*     * to us, so strip it off.
*
**/

    if (buf[0] == '<') {
                       
        char *match = strchr(buf, '>');
        if (match != NULL) {
            nread -= (match+1-buf);
            memmove(buf, match+1, nread+1);
        }
    }

     return nread;
}

int wifi_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
{
    int res;
    int ctrlfd = wpa_ctrl_get_fd(ctrl);
    struct pollfd rfds[2];


    memset(rfds, 0, 2 * sizeof(struct pollfd));

    rfds[0].fd = ctrlfd;
    rfds[0].events |= POLLIN;

//  rfds[1].fd = exit_sockets[1];
// rfds[1].events |= POLLIN;

    res = poll(rfds, 1, -1);
    if (res < 0) {
        ALOGE("Error poll = %d", res);
        return res;
    }

    if (rfds[0].revents & POLLIN) {
        return wpa_ctrl_recv(ctrl, reply, reply_len);
    } else {
        ALOGD("Received on exit socket, terminate");
        return -1;
    }

    return 0;
}

#include <sys/wait.h>
#include <signal.h>  
static void signal_hander(int no)  
{
    //处理子进程退出信号  
    int child_status;  
    wait(&child_status);  
    ALOGI("child exited status %d", child_status);  
}  

static void signal_alarm(int no)
{
    ALOGD("stat count %d/%d", sta_count, MAX_CLIENT );
    if (sta_count < MAX_CLIENT && ctrl_conn)
        wpa_ctrl_cmd(ctrl_conn, wpa_cmd_find);

    alarm(60);
}

static int checkexit(const char * pfile)
{
    if (pfile == NULL)
    {   
       return -1; 
    }   


    ALOGD("check exit %s", pfile);
    int lockfd = open(pfile,O_RDWR|O_CREAT);
    ALOGD("lockfd = %d",lockfd);
    if (lockfd == -1) 
    {   
       return -2; 
     }   
    int iret = flock(lockfd,LOCK_EX|LOCK_NB);
    ALOGD("iret %d", iret);
    if (iret == -1) 
    {   
       return -3; 
     }   

    return 0;

}



static int get_mac_value(char *buf, char *prop_value, int prop_size)
{
    const char *delim = " ";
    char *save_ptr;
    char *sta_mac;
    int ret;
    int i;

    if (!(sta_mac = strtok_r(buf, delim, &save_ptr))) 
    {
        ALOGE(" get mac mail!"); 
        return -1;
    }

    
    ALOGI("new connect device mac %s", sta_mac);

    if ((prop_size <  strlen(sta_mac) + 1))
    {
        ALOGE("prop size not enough!");
        return -1;
    }
    
    memcpy(prop_value, sta_mac,strlen(sta_mac));
     //check emtpy gthread_table and insert
    for (i = 0; i < MAX_CLIENT; i++)
    {
        ALOGD("%d pid %d ", i, gthread_table[i].pid);
        if (gthread_table[i].pid == 0)
            break;
    }

    if (i >= MAX_CLIENT)
    {
        ALOGE("wfd instance exceed!!!");
        ret = -1;
    }
    else
    { 
        ret = i;
    }

    return  ret;
}

 //ruijie get event buf IFNAME=p2p-wlan0-11 <3>AP-STA-CONNECTED b2:e2:35:c9:fd:05 p2p_dev_addr=b2:e2:35:c9:fd:05
 //ruijie get event buf P2P-GROUP-STARTED p2p0 client ssid="DIRECT-0w-hanqingwu" freq=2432 psk=203e4794e937fdd986ad9ffb964400699813e362e8c1265b0ca86661c67dd04f go_dev_addr=b2:e2:35:c9:fd:05 [PERSISTENT]
static  int  process_wpa_ap_sta_connect_event(const char *buf, char *prop_value, int prop_size, bool  *isclient)
{
    char *p;

    *isclient = 0;

    if (p = strstr(buf, AP_STA_CONNECTED))
    {
        ALOGD("match %s", AP_STA_CONNECTED);
        p += strlen(AP_STA_CONNECTED);

        return get_mac_value(p, prop_value, prop_size);
    }

   
    else if (p = strstr(buf,P2P_EVENT_GROUP_STARTED))
    {
        ALOGD("match %s", P2P_EVENT_GROUP_STARTED );
        p = strstr(p, "client");
        if (p == NULL)
            return -1;
    
        p = strstr(p, "go_dev_addr");
        if (p == NULL)
           return -1;

        p += strlen("go_dev_addr=");

        *isclient = 1;

        return get_mac_value(p, prop_value, prop_size);
    }

    return  -1;

}

static int clear_thread_table(const char *sta_mac)
{
    int ret = -1;
    //kill thread
    for (int i = 0; i < MAX_CLIENT ; i++)
    {
        ALOGD("check %d  pid %d ,mac %s", i, gthread_table[i].pid, gthread_table[i].mac);
        if (strstr((char *)gthread_table[i].mac, sta_mac))
        {
            ALOGI("%s disconenct succes ", gthread_table[i].mac);

            kill(gthread_table[i].pid, SIGKILL);
            gthread_table[i].pid = 0;
            memset(gthread_table[i].mac, 0, MAC_SIZE);

            ret = 0;
            break;
        }

        if (gthread_table[i].isclient)
        {
            if (memcmp(gthread_table[i].mac, sta_mac,11)==0 && (memcmp(&gthread_table[i].mac[13],&sta_mac[13],4) == 0))
            {
                ALOGI("%s disconenct succes client ", gthread_table[i].mac);

                kill(gthread_table[i].pid, SIGKILL);
                gthread_table[i].pid = 0;
                gthread_table[i].isclient = 0;
                memset(gthread_table[i].mac, 0, MAC_SIZE);

                ret = 0;
                break;
            }
        }
    }

    return ret;
}

//ruijie get event buf IFNAME=p2p-wlan0-1 <3>AP-STA-DISCONNECTED b2:e2:35:c9:fd:05 p2p_dev_addr=b2:e2:35:c9:fd:05
//ruijie get event buf IFNAME=p2p0 <3>CTRL-EVENT-DISCONNECTED bssid=b2:e2:35:c9:fd:05 reason=0
static int  process_wpa_ap_sta_disconnect_event(const char *buf)
{
    char *p = NULL;
    int ret = -1;
   
    if (p = strstr(buf,AP_STA_DISCONNECTED))
    {
        ALOGD("match %s",AP_STA_DISCONNECTED);
        p += strlen(AP_STA_DISCONNECTED);
     }
    else if (p = strstr(buf, WPA_EVENT_DISCONNECTED))
    {
        ALOGD("match %s",WPA_EVENT_DISCONNECTED);
        p += strlen(WPA_EVENT_DISCONNECTED);

        if (memcmp(p,"bssid=",strlen("bssid=")) == 0)
        {
           p += strlen("bssid=");
        }
    }

    if (p)
    {
        char *sta_mac = NULL;
        const char *delim = " ";
        char *save_ptr;

        if (!(sta_mac = strtok_r(p, delim, &save_ptr))) 
        {
            ALOGE("get mac fail ");
            return ret;
        }


        ALOGD("disconnect sta_mac %s", sta_mac);
        ret = clear_thread_table(sta_mac);
   
    }

    return ret;

}
//P2P-GO-NEG-REQUEST b2:e2:35:c9:fd:05 dev_passwd_id=4 go_intent=15
static char * process_wpa_go_neg_request_event(const char *buf)
{
    char *sta_mac = NULL;
    char *p = strstr(buf,P2P_EVENT_GO_NEG_REQUEST);
    if (p)
    {
        const char *delim = " ";
        char *save_ptr;

        ALOGD("enter process go negotiation request ");
        p += strlen(P2P_EVENT_GO_NEG_REQUEST);
        if (!(sta_mac = strtok_r(p, delim, &save_ptr))) 
            ALOGE("get mac fail ");
    }  

    return sta_mac; 
}

static int wpa_ctrl_cmd(struct wpa_ctrl *ctrl_conn, const char *cmd)
{
    char reply[1024];
    size_t  reply_len;
    int ret = -1;

    if (ctrl_conn && cmd)
    {
        ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd),reply,&reply_len,NULL);
        ALOGD("wpa ctrl cmd %s, ret %d",cmd, ret);
    }

    return ret; 
}

int main(int argc, char **argv)
{

    char prop_value[PROPERTY_VALUE_MAX];
    char prop_value_rtp_ip[PROPERTY_VALUE_MAX];
    char prop_value_rtp_port[PROPERTY_VALUE_MAX];
    
   // using namespace android;
	ALOGI("start---------WFD---Multiple  Display");
    
    if (checkexit(pid_wfd) < 0)
        return 0;
    
    memset(gthread_table, 0, sizeof(struct thread_table) * MAX_CLIENT);
    signal(SIGCHLD,signal_hander);  
    signal(SIGALRM,signal_alarm);

    
    int index = 0;
    property_get("net.wfd.addr",prop_value,NULL);
    property_get("persist.wfd.recv_ip", prop_value_rtp_ip, "127.0.0.1");
    property_get("persist.wfd.recv_port", prop_value_rtp_port, "19000");


    int wpa_cli_attached = 0;
    const char *global = "wlan0";
    char buf[1024];
    bool isclient = 0;


    ctrl_conn = wpa_ctrl_open(global);
    
    wpa_ctrl_cmd(ctrl_conn, wpa_cmd_find);
    wpa_ctrl_cmd(ctrl_conn, wpa_cmd_set_wifi_dislay);
    wpa_ctrl_cmd(ctrl_conn, wpa_cmd_set_subelem);
    alarm(60);

    mon_conn = wpa_ctrl_open(global);
    ALOGI("mon_conn %p", mon_conn);
    if (mon_conn) 
    {
        if (wpa_ctrl_attach(mon_conn) == 0)
        {
            ALOGD("wpa_ctrl_attach pass !");
            wpa_cli_attached = 1;
 //ruijie get event buf IFNAME=p2p-wlan0-11 <3>AP-STA-CONNECTED b2:e2:35:c9:fd:05 p2p_dev_addr=b2:e2:35:c9:fd:05
                //client  ruijie get event buf IFNAME=p2p-wlan0-3 <3>CTRL-EVENT-CONNECTED - Connection to b2:e2:35:c9:fd:05 completed [id=0 id_str=]
               
            while (wifi_wait_for_event(buf, sizeof(buf)) > 0)
            {
                ALOGI("ruijie get event buf %s", buf);

                memset(prop_value, 0, sizeof(prop_value));
                //process connect event 
                if ((index = process_wpa_ap_sta_connect_event(buf, prop_value, sizeof(prop_value),&isclient)) >= 0)
                {
                    pid_t pid;

                    pid = fork();
                    if (pid < 0)
                        ALOGE("fork fail!");
                    else if (pid == 0)
                    {
                        ALOGI("start wfd %s ...", prop_value);
                        goto start_wfd;
                        break;
           
                    }
                    else 
                    {
                        gthread_table[index].pid = pid;
                        gthread_table[index].isclient = isclient;
                        memcpy(gthread_table[index].mac, prop_value, MAC_SIZE);
                        
                        ALOGI("parent insert %d gthread_table   pid %d, mac %s client %d", index,  gthread_table[index].pid, gthread_table[index].mac, isclient);

                        sta_count++;
                        if (index == MAX_CLIENT - 1)
                            wpa_ctrl_cmd(ctrl_conn, wpa_cmd_stop_find);
                    }
                }

                //process  disconnect event, restart find 
                if (process_wpa_ap_sta_disconnect_event(buf) == 0)
                {
                    wpa_ctrl_cmd(ctrl_conn, wpa_cmd_find);
                    if (sta_count)
                        sta_count--;

                    ALOGD("disconneced  sta_count = %d", sta_count);
                }


                if (sta_count < MAX_CLIENT)
                {
                    char *sta_mac = process_wpa_go_neg_request_event(buf);
                    if (sta_mac)
                    {
                        char cmd_buf[128];

                        sprintf(cmd_buf, "%s %s",wpa_cmd_peer,sta_mac);
                        wpa_ctrl_cmd(ctrl_conn, cmd_buf);

                        sprintf(cmd_buf, "%s %s pbc persistent go_intent=%d",wpa_cmd_connect,sta_mac, DEFAULT_GROUP_INTENT);
                        wpa_ctrl_cmd(ctrl_conn, cmd_buf);

                    }
                }
                

                
            }
        
        } else {
            ALOGI("Failed to open monitor "
                   "connection through global "
                   "control interface\n");
        }
    }
	

    ALOGD("exit wpa_ctrl ");

    if (wpa_cli_attached)
        wpa_ctrl_detach(mon_conn);

    wpa_ctrl_close(mon_conn);
    wpa_ctrl_close(ctrl_conn);
	

start_wfd:

    using  namespace android;
    ProcessState::self()->startThreadPool();
    DataSource::RegisterDefaultSniffers();
	AString connectAddr;
    AString connectToHost;
	int32_t iCount =0;
    int32_t connectToPort = -1;
#if 0
	int32_t iCount =0;
    AString connectToHost;
    int32_t connectToPort = -1;
    AString uri;

    AString listenOnAddr;
    int32_t listenOnPort = -1;
	AString connectAddr;



  //  char prop_value[PROPERTY_VALUE_MAX];
//    property_get("net.wfd.addr",prop_value,NULL);

    int res;
    while ((res = getopt(argc, argv, "s:hc:l:u:")) >= 0) {
        switch (res) {
            case 'c':
            {
		ALOGE("start---------WFD c");
                const char *colonPos = strrchr(optarg, ':');

                if (colonPos == NULL) {
                    connectToHost = optarg;
                    connectToPort = WifiDisplaySource::kWifiDisplayDefaultPort;
                } else {
                    connectToHost.setTo(optarg, colonPos - optarg);

                    char *end;
                    connectToPort = strtol(colonPos + 1, &end, 10);

                    if (*end != '\0' || end == colonPos + 1
                            || connectToPort < 1 || connectToPort > 65535) {
                        fprintf(stderr, "Illegal port specified.\n");
                        exit(1);
                    }
                }
                break;
            }

	    case 's':
	    {
		char ipAddr[PROPERTY_VALUE_MAX];
                const char *colonPos = strrchr(optarg, ':');
		ALOGE("start---------WFD s optarg=%s",optarg);
                if (colonPos == NULL) {
                    connectAddr = optarg;
                    connectToPort = WifiDisplaySource::kWifiDisplayDefaultPort;
                } else {
                    connectAddr.setTo(optarg, colonPos - optarg);

                    char *end;
                    connectToPort = strtol(colonPos + 1, &end, 10);

                    if (*end != '\0' || end == colonPos + 1
                            || connectToPort < 1 || connectToPort > 65535) {
                        fprintf(stderr, "Illegal port specified.\n");
                        exit(1);
                    }
		    ALOGE("start---------WFD s connectAddr=%s",connectAddr.c_str());
		    memset(ipAddr,0,sizeof(ipAddr));
		    char buf[PROPERTY_VALUE_MAX];
                    int try_times = 20;
                    bool dhcp_result = false;
                    while (try_times--){
                    	property_get("dhcp.p2p.result", buf, NULL);
                        if (!strcmp(buf, "ok")){
                        	ALOGD("dhcp client udpate status %s", buf);
                            dhcp_result = true;
                            break;
                        }
                            usleep(1000*100); //sleep 100ms at one time 
                    }

                    if (dhcp_result){
                    	property_get("dhcp.p2p.server", ipAddr, NULL);
                        ALOGD("Client Role: connect to Host %s:%d", ipAddr,connectToPort);
                        connectToHost = ipAddr;
                    }else{
			for(iCount =0;iCount <TRY_ARP_COUNT;iCount++)
			{
				if(Search_ipAddr(connectAddr.c_str(),ipAddr) >0)
					break;
				usleep(300*1000);

			}
			if(iCount >=TRY_ARP_COUNT)
			{
				ALOGE("####iCount =%d > (TRY_ARP_COUNT=%d)",iCount,TRY_ARP_COUNT);
				exit(1);
			}
						
			connectToHost =(AString)ipAddr;
			ALOGE("start---------WFD s connectToHost =%s,connectToPort=%d",connectToHost.c_str(),connectToPort);
		   }		
		}		
		break;
	    }
            case 'u':
            {
                uri = optarg;
                break;
            }

            case 'l':
            {
                const char *colonPos = strrchr(optarg, ':');

                if (colonPos == NULL) {
                    listenOnAddr = optarg;
                    listenOnPort = WifiDisplaySource::kWifiDisplayDefaultPort;
                } else {
                    listenOnAddr.setTo(optarg, colonPos - optarg);

                    char *end;
                    listenOnPort = strtol(colonPos + 1, &end, 10);

                    if (*end != '\0' || end == colonPos + 1
                            || listenOnPort < 1 || listenOnPort > 65535) {
                        fprintf(stderr, "Illegal port specified.\n");
                        exit(1);
                    }
                }
                break;
            }

            case '?':
            case 'h':
            default:
                usage(argv[0]);
                exit(1);
        }
    }
#endif


#if 1
         char ipAddr[PROPERTY_VALUE_MAX];
         const char *colonPos = strrchr(prop_value, ':');
         ALOGE("start---------WFD s optarg=%s",prop_value);
         {
    /* 
         if (colonPos == NULL) {
            connectAddr = prop_value;
            connectToPort = WifiDisplaySource::kWifiDisplayDefaultPort;   //7236
         } else {
            connectAddr.setTo(prop_value, colonPos - prop_value);
            char *end;
            connectToPort = strtol(colonPos + 1, &end, 10);

            if (*end != '\0' || end == colonPos + 1
                 || connectToPort < 1 || connectToPort > 65535) {
                  fprintf(stderr, "Illegal port specified.\n");
                  exit(1);
            }
*/
            connectAddr = prop_value;
            connectToPort = WifiDisplaySource::kWifiDisplayDefaultPort;   //7236
 
            ALOGE("start---------WFD s connectAddr=%s",connectAddr.c_str());
            memset(ipAddr,0,sizeof(ipAddr));
            char buf[PROPERTY_VALUE_MAX];
            int try_times = 20;
            bool dhcp_result = false;
            while (try_times--){
                 property_get("dhcp.p2p.result", buf, NULL);
                 if (!strcmp(buf, "ok")){
                       ALOGD("dhcp client udpate status %s", buf);
                       dhcp_result = true;
                       break;
                 }
                       usleep(1000*100); //sleep 100ms at one time 
            }
         
            if (dhcp_result){
                property_get("dhcp.p2p.server", ipAddr, NULL);
                ALOGD("Client Role: connect to Host %s:%d", ipAddr,connectToPort);
                connectToHost = ipAddr;
            }else{
                for(iCount =0;iCount <TRY_ARP_COUNT;iCount++)
                {
                   if(Search_ipAddr(connectAddr.c_str(),ipAddr, iCount) >0)
                          break;
                    usleep(300*1000);

                }
                if(iCount >=TRY_ARP_COUNT)
                {
                   if(Search_ipAddr(connectAddr.c_str(),ipAddr, iCount) < 0)
                   {
                        ALOGE("####iCount =%d > (TRY_ARP_COUNT=%d)",iCount,TRY_ARP_COUNT);
                       //clear gthread_table
                       clear_thread_table(connectAddr.c_str());
                       exit(1);
                   }   
                }
                                                
                connectToHost =(AString)ipAddr;
                ALOGE("start---------WFD s connectToHost =%s,connectToPort=%d",connectToHost.c_str(),connectToPort);
            }          
         }
    
#endif

/*
    char ipAddr[PROPERTY_VALUE_MAX];
    char macAddr[PROPERTY_VALUE_MAX];


    get_device_mac_ip(NULL, ipAddr);

    connectToHost = ipAddr;
    connectToPort = 7236;
    ALOGE("start---------WFD s connectToHost =%s,connectToPort=%d",connectToHost.c_str(),connectToPort);
*/
//////////////////////////////////
#if 0

    if (connectToPort >= 0 && listenOnPort >= 0) {
        fprintf(stderr,
                "You can connect to a source or create one, "
                "but not both at the same time.\n");
        exit(1);
    }

    if (listenOnPort >= 0) {
		ALOGD("listenOnPort listenOnPort %d",listenOnPort);
        createSource(listenOnAddr, listenOnPort);
        exit(0);
    }

    if (connectToPort < 0 && uri.empty()) {
        fprintf(stderr,
                "You need to select either source host or uri.\n");

        exit(1);
    }

    if (connectToPort >= 0 && !uri.empty()) {
        fprintf(stderr,
                "You need to either connect to a wfd host or an rtsp url, "
                "not both.\n");
        exit(1);
    }
    usleep(800*1000);
#endif

///
/*
	ALOGE("This demo ---------WFD s connectToPort=%d connectToHost.c_str() %s",connectToPort,connectToHost.c_str() );
	ALOGE("------------Produce Over ---------------");

    return 0;
*/
    
    sp<ANetworkSession> session = new ANetworkSession;
    session->start(prop_value_rtp_ip, atol(prop_value_rtp_port) + index * 2);

    sp<ALooper> looper = new ALooper;
    looper->setName("wfd");

    sp<WifiDisplaySink> sink = new WifiDisplaySink(session);
    looper->registerHandler(sink);
    if (connectToPort >= 0) {
    	ALOGE("start---------WFD s connectToPort=%d connectToHost.c_str() %s",connectToPort,connectToHost.c_str() );
        sink->start(connectToHost.c_str(), connectToPort);
    } 
#if 0  
        else {
    	ALOGE("start---------WFD s connectToPort=%d uri.c_str() %s",connectToPort,uri.c_str() );
        sink->start(uri.c_str());
    }
#endif
    looper->start(true /* runOnCallingThread */);
    return 0;
}
